﻿using AllinpayEleMe.Widget;
using Application;
using Application.Dao;
using AYQQMGR2018.Views.Shared;
using Event;
using IWshRuntimeLibrary;
using org.diordna.eventbus;
using System;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interop;
using Utils;
using 小工具.Views.EditApplication;

namespace 小工具.Views.Shared.creator
{
    public class ApplicationToolCreator : BaseAyToolBoxExtraRightButtonCreator<string, CApplication>
    {
        private static readonly ushort PIC_SIZE = 40;

        public override AyToolBoxExtraRightButton CreateBtn(CApplication value)
        {

            AyToolBoxExtraRightButton btn = CreateBtn(value, value.Name, GetAppImagePath(value));
            btn.Click += Btn_Click;

            // 添加右键菜单
            ContextMenu menu = new ContextMenu();
            MenuItem editItem = new MenuItem();
            editItem.Header = "编辑";
            editItem.Click += Edit_Click;
            menu.Items.Add(editItem);
            MenuItem copyItem = new MenuItem();
            copyItem.Header = "保存";
            copyItem.Click += Copy_Click;
            menu.Items.Add(copyItem);
            MenuItem openItem = new MenuItem();
            openItem.Header = "打开文件夹";
            openItem.Click += OpenDir_Click;
            menu.Items.Add(openItem);
            MenuItem delItem = new MenuItem();
            delItem.Header = "删除";
            delItem.Click += Del_Click;
            menu.Items.Add(delItem);
            btn.ContextMenu = menu;

            return btn;
        }

        public override AyToolBoxExtraRightButton CreateBtn(string t)
        {

            CApplication value = GetValue(t);
            new AppDao().Insert(value);
            return CreateBtn(value);
        }

        protected override CApplication GetValue(string t)
        {
            CApplication app = DealDropPath(t, "");

            app = CreateApplication(app);
            return app;
        }

        private void Edit_Click(object sender, RoutedEventArgs e)
        {
            AyToolBoxExtraRightButton btn = Event2Btn(e);
            EditApplicationView edit = new EditApplicationView((CApplication)btn.Value);
            edit.ShowDialog();
        }

        private void Copy_Click(object sender, RoutedEventArgs e)
        {
            AyToolBoxExtraRightButton btn = Event2Btn(e);
            CApplication app = (CApplication)btn.Value;
            EditApplicationView edit = new EditApplicationView(app.Clone());
            edit.ShowDialog();
        }

        private void OpenDir_Click(object sender, RoutedEventArgs e)
        {
            AyToolBoxExtraRightButton btn = Event2Btn(e);
            CApplication app = (CApplication)btn.Value;
            string dir = app.Path;
            if (app.Type == 0)
            {
                dir = Path.GetDirectoryName(dir);
            }

            OpenDir(dir);
        }

        private void Del_Click(object sender, RoutedEventArgs e)
        {
            AyToolBoxExtraRightButton btn = Event2Btn(e);
            AlertDialog.NewInstance()
                .AddDragMove()
                .SetInfo("是否需要删除此应用？")
                .SetPositiveButton("删除", () =>
                {
                    new AppDao().Delete((CApplication)btn.Value);
                    EventBus.Instance.Publish(new BaseEvent(MainViewEvent.NOTIFY_APP_INIT));
                    return true;
                })
                .Show();
        }

        private void Btn_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            AyToolBoxExtraRightButton btn = sender as AyToolBoxExtraRightButton;
            CApplication app = (CApplication)btn.Value;
            OpenApplication(app);
        }

        private CApplication CreateApplication(CApplication app)
        {

            app.Path = Path.GetFullPath(app.Path);
            if (app.Name.IsNullAndTrimAndEmpty())
            {
                app.Name = Path.GetFileNameWithoutExtension(app.Path);
            }
            app.Guid = Guid.NewGuid().ToString("D");

            CreateAppThumb(app);

            SaveApplication(app);

            return app;
        }

        private void SaveApplication(CApplication app)
        {
            new AppDao().Insert(app);
        }

        private void CreateAppThumb(CApplication app)
        {
            if (!System.IO.File.Exists(GetAppImagePath(app)))
            {
                Bitmap bm = WindowsThumbnailProvider.GetThumbnail(app.Path, PIC_SIZE, PIC_SIZE, ThumbnailOptions.None);
                BitmapUtils.Bitmap2File(bm, GetAppImagePath(app));
            }
        }

        private string GetAppImagePath(CApplication app)
        {
            string path = Path.GetFullPath(@".\img\app\" + app.Guid + ".png");
            FileInfo info = new FileInfo(path);
            if (!info.Directory.Exists)
            {
                info.Directory.Create();
            }

            return path;
        }

        [DllImport("shell32.dll")]
        public static extern IntPtr ShellExecute(IntPtr hwnd, //窗口句柄
                                                 string lpOperation, //指定要进行的操作
                                                 string lpFile,  //要执行的程序、要浏览的文件夹或者网址
                                                 string lpParameters, //若lpFile参数是一个可执行程序，则此参数指定命令行参数
                                                 string lpDirectory, //指定默认目录
                                                 int nShowCmd   //若lpFile参数是一个可执行程序，则此参数指定程序窗口的初始显示方式(参考如下枚举)
            );
        public enum ShowWindowCommands : int
        {
            SW_HIDE = 0,
            SW_SHOWNORMAL = 1,
            SW_NORMAL = 1,
            SW_SHOWMINIMIZED = 2,
            SW_SHOWMAXIMIZED = 3,
            SW_MAXIMIZE = 3,
            SW_SHOWNOACTIVATE = 4,
            SW_SHOW = 5,  //显示一个窗口，同时令其进入活动状态
            SW_MINIMIZE = 6,
            SW_SHOWMINNOACTIVE = 7,
            SW_SHOWNA = 8,
            SW_RESTORE = 9,
            SW_SHOWDEFAULT = 10,
            SW_MAX = 10
        }


        private void OpenApplication(CApplication app)
        {
            ShellExecute(IntPtr.Zero, "open", app.Path, app.Argument, null, (int)ShowWindowCommands.SW_SHOW);
        }

        private void OpenDir(string path)
        {
            ShellExecute(IntPtr.Zero, "open", path, null, null, (int)ShowWindowCommands.SW_SHOW);
        }

        private AyToolBoxExtraRightButton Event2Btn(RoutedEventArgs e)
        {
            ContextMenu menu = (ContextMenu)ContextMenu.ItemsControlFromItemContainer((MenuItem)e.OriginalSource);
            AyToolBoxExtraRightButton btn = menu.PlacementTarget as AyToolBoxExtraRightButton;
            return btn;
        }

        enum FileType
        {
            FILE = 0,
            LINK,
            DIR,
            UNKNOWN,
        }
        private FileType GetFileType(string path)
        {
            FileInfo info = null;
            try
            {
                info = new FileInfo(path);
            }
            catch
            {
                AlertDialog.NewInstance()
                    .AddDragMove()
                    .SetInfo("文件路径不合法！")
                    .Show();
                return FileType.UNKNOWN;
            }
            if (info.Attributes == FileAttributes.Directory)
            {
                return FileType.DIR;
            }
            else
            {
                if (!System.IO.File.Exists(path))
                {
                    return FileType.UNKNOWN;
                }

                if (".lnk".Equals(Path.GetExtension(path)))
                {
                    return FileType.LINK;
                }
                return FileType.FILE;
            }
        }

        private CApplication DealDropPath(string path, string argument)
        {

            FileType type = GetFileType(path);

            CApplication app = new CApplication();
            app.Path = path;
            app.Argument = argument;

            switch (type)
            {
                case FileType.FILE:
                    app.Type = 0;
                    return app;
                case FileType.DIR:
                    app.Type = 1;
                    return app;
                case FileType.LINK:
                    app = SetApplicationFromLink(app);
                    return DealDropPath(app.Path, app.Argument);
                default:
                    return null;
            }
        }

        private CApplication SetApplicationFromLink(CApplication app)
        {
            IWshShell shell = new WshShell();
            IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(app.Path);
            app.Path = shortcut.TargetPath;
            app.Argument = shortcut.Arguments;
            return app;
        }
    }
}